module canvas.floatcanvas;

import canvas.abstractcanvas;
import utils.vector2;
import utils.color;
import derelict.devil.il;
import std.stdio;
import std.string;


class FloatCanvas: public AbstractCanvas {
    private RGBColor[] mData;

    this(Vector2i res) {
        super(res);

        mData = new RGBColor[res.x * res.y];
        clearCanvas(RGBColor(0,0,0));
    }

    this() {
        this(Vector2i(0, 0));
    }

    public void enterRenderMode() {
        //nix
    }

    public void leaveRenderMode() {
        //nix
    }

    public void drawPixel(Vector2i pos, RGBColor col) {
        mData[pos.y*mRes.x + pos.x] = col;
    }

    public void getPixelColor(Vector2i pos, out RGBColor col) {
        col = mData[pos.y*mRes.x + pos.x];
    }

    public void clearCanvas(RGBColor col) {
        for (int i = 0; i < mRes.x * mRes.y; i++) {
            mData[i] = col;
        }
    }

    ///change size and allocate new buffer
    public void resizeCanvas(Vector2i newRes) {
        mRes = newRes;
        mData.length = mRes.x * mRes.y;
        writefln("Resizing FloatCanvas to %d x %d",mRes.x, mRes.y);
    }

    ///load an image, using DevIL
    ///canvas will be resized to fit image size
    ///throws Exception on error
    public void loadImageFile(char[] filename) {
        ILuint imgName;
        ilGenImages(1, &imgName);
        ilBindImage(imgName);
        scope(exit) ilDeleteImages(1, &imgName);

        //make sure image is not upside-down
        //this seems to mess up hdr images (???)
        //ilEnable(IL_ORIGIN_SET);
        //ilOriginFunc(IL_ORIGIN_LOWER_LEFT);

        if (!ilLoadImage(toStringz(filename))) {
            throw new Exception("Failed to load image " ~ filename ~ " : " ~
                std.string.toString(ilGetError()));
        }

        int w = ilGetInteger(IL_IMAGE_WIDTH);
        int h = ilGetInteger(IL_IMAGE_HEIGHT);
        int p = ilGetInteger(IL_IMAGE_BYTES_PER_PIXEL);
        writefln("Image File %s: %dx%d, %d BPP", filename, w, h, p*8);
        resizeCanvas(Vector2i(w,h));

        if (!ilCopyPixels(0,0,0,w,h,1,IL_RGB,IL_FLOAT,mData.ptr)) {
            //throw new Exception("Failed to load image " ~ filename ~ " : " ~
            //    std.string.toString(ilGetError()));
            //%/$&E$/%/!""!!!
            //doesn't seem to support IL_FLOAT?
            ubyte tmp[];
            tmp.length = w*h*3;
            if (!ilCopyPixels(0,0,0,w,h,1,IL_RGB,IL_UNSIGNED_BYTE,tmp.ptr)) {
                throw new Exception("Failed to load image " ~ filename ~ " : " ~
                    std.string.toString(ilGetError()));
            }
            Vector2i pos;
            RGBColor col;
            for (int x = 0; x < w; x++) {
                for (int y = 0; y < h; y++) {
                    pos.x = x;
                    pos.y = y;
                    col.r = 255.0f / cast(float)(tmp[(y*w+x)*3+0]);
                    col.g = 255.0f / cast(float)(tmp[(y*w+x)*3+1]);
                    col.b = 255.0f / cast(float)(tmp[(y*w+x)*3+2]);
                    drawPixel(pos, col);
                }
            }
            delete tmp;
        }



        writefln("%s loaded in FloatRenderCanvas.",filename);
    }
}
